Skip to content

Require discoverable credentials and user verification in README examples#501

Open
ttanimichi wants to merge 2 commits into
cedarcode:masterfrom
ttanimichi:authenticator-selection
Open

Require discoverable credentials and user verification in README examples#501
ttanimichi wants to merge 2 commits into
cedarcode:masterfrom
ttanimichi:authenticator-selection

Conversation

@ttanimichi

@ttanimichi ttanimichi commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

Most modern platform authenticators and passkey managers already support both discoverable credentials and user verification. This PR updates the README walkthrough examples to require them consistently across both the registration and authentication flows.

Most modern platform authenticators and passkey managers already support both Discoverable Credentials and user verification. Wouldn't explicitly requiring them in options_for_create lead to a simpler and more straightforward authentication flow?
@ttanimichi ttanimichi force-pushed the authenticator-selection branch from 503f034 to db3fa32 Compare June 27, 2026 14:04
@ttanimichi ttanimichi changed the title Add authenticator_selection to options_for_create examples Require discoverable credentials and user verification in README examples Jun 28, 2026

@santiagorodriguez96 santiagorodriguez96 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @ttanimichi! Improving the README is something I've had in mind for a while, and there's definitely room for it – for now, I think it makes sense to include examples of how to set the user_verification and resident_key options. However, there's one thing I'd like to sort out before merging.

The README walkthrough is meant as an example of how to use the gem, but it's easy for it to be read as a reference implementation – so the option values it shows can end up being treated as recommended defaults. My concern is that requiring resident_key and user_verification in the walkthrough could steer someone using the gem for implementing a 2FA flow toward a more constrained setup than they need:

  • resident_key: "required" shrinks the set of usable authenticators – any that can't create a discoverable credential are excluded from selection – and uses up the limited discoverable-credential storage on roaming keys that do support it, so a key that's already full fails the registration. 2FA needs none of this, since you already have an allow-list.
  • user_verification: "required" likewise excludes authenticators that can't perform user verification, and forces a PIN/biometric even though the credential is already the second factor; "discouraged" (or "preferred") is often the better fit there.

Rather than bake one profile in as the default, could we keep your additions but annotate the decision points, so the example serves both 2FA and passwordless without prescribing either? Left inline suggestions for that.

Comment thread README.md
Comment on lines +179 to +183
exclude: user.credentials.map { |c| c.webauthn_id },
authenticator_selection: {
resident_key: "required",
user_verification: "required"
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
exclude: user.credentials.map { |c| c.webauthn_id },
authenticator_selection: {
resident_key: "required",
user_verification: "required"
}
exclude: user.credentials.map { |c| c.webauthn_id },
authenticator_selection: {
resident_key: "discouraged", # For a passwordless login or 2FA. Use "required" for a passkey-based (passwordless and usernameless) login.
user_verification: "required" # For a passwordless or passkey-based (passwordless and usernameless) login. Use "discouraged" for 2FA.
}

Comment thread README.md

begin
webauthn_credential.verify(session[:creation_challenge])
webauthn_credential.verify(session[:creation_challenge], user_verification: true)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
webauthn_credential.verify(session[:creation_challenge], user_verification: true)
# Enforce user verification (pairs with the "required" request above). Omit for 2FA.
webauthn_credential.verify(session[:creation_challenge], user_verification: true)

Comment thread README.md
Comment on lines +231 to +234
options = WebAuthn::Credential.options_for_get(
allow: user.credentials.map { |c| c.webauthn_id },
user_verification: "required"
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
options = WebAuthn::Credential.options_for_get(
allow: user.credentials.map { |c| c.webauthn_id },
user_verification: "required"
)
options = WebAuthn::Credential.options_for_get(
# Pass `allow` when the user is already known (passwordless/2FA/reauth).
# For a passkey-based (usernameless and passwordless) login, omit it and resolve the user from `user_handle` after `from_get`.
allow: user.credentials.map { |c| c.webauthn_id },
user_verification: "required" # For a passwordless or passkey-based (passwordless and usernameless) login. Use "discouraged" for 2FA.
)

Comment thread README.md
Comment on lines +270 to +271
sign_count: stored_credential.sign_count,
user_verification: true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
sign_count: stored_credential.sign_count,
user_verification: true
sign_count: stored_credential.sign_count,
user_verification: true # For a passwordless or passkey-based (passwordless and usernameless) login. Omit for 2FA.

Comment thread README.md
Comment on lines +301 to +305
extensions: { appidExclude: domain.to_s },
authenticator_selection: {
resident_key: "required",
user_verification: "required"
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
extensions: { appidExclude: domain.to_s },
authenticator_selection: {
resident_key: "required",
user_verification: "required"
}
extensions: { appidExclude: domain.to_s },
authenticator_selection: {
resident_key: "discouraged", # For a passwordless login or 2FA. Use "required" for a passkey-based (passwordless and usernameless) login.
user_verification: "required" # For a passwordless or passkey-based (passwordless and usernameless) login. Use "discouraged" for 2FA.
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants